package factory

import (
	"fmt"
	"log"
	"time"
)

type (
	Cache interface {
		Get(key string) ([]byte, error)
 		Put(key string, val interface{}, timeout time.Duration) error
		Delete(key string) error
		Incr(key string) error
		Decr(key string) error
		IsExist(key string) bool
		ClearAll() error
		StartAndConfigure(ops ...CacheOption) error
		Close() error
	}

	CacheInstance func() Cache

	CacheOption func(c Cache)
)

var cacheFactory = make(map[string]CacheInstance)

func Register(name string, factory CacheInstance) {
	if factory == nil {
		log.Panic("cache: Register adapter is nil")
	}

	if _, ok := cacheFactory[name]; ok {
		log.Panic("cache: Register called twice for adapter " + name)
	}
	cacheFactory[name] = factory
}

func NewCache(name string, ops ...CacheOption) (c Cache, err error) {
	instance, ok := cacheFactory[name]
	if !ok {
		err = fmt.Errorf("cache: unknown adapter name %q (forgot to import?)", name)
		return
	}

	c = instance()
	err = c.StartAndConfigure(ops...)
	if err != nil {
		c = nil
	}
	return
}
